其他
举杯邀Frida,对影成三题
本文为看雪论坛优秀文章
看雪论坛作者ID:一颗金柚子
本文为看雪安卓高研2w班(6月班)优秀学员作品。
下面先让我们来看看讲师对学员学习成果的点评,以及学员的学习心得吧!
这位学员的解题思路有几个亮点:
1. Frida内置的JSON其实功能非常有限,但是使用谷歌的gson效果就完全不同了,几乎可以打印所有java对象,点赞!
2. “反编译的结果不能完全相信”,使用objection去内存中枚举类并打印调用栈,进一步确认类的名称和执行流程,这样是比较严谨的。
3. Frida hook nativelibc strcmp 判断第二个参数为“REJECT”,体现了尽量不要改so,而且修改系统库的思想,非常优秀。
其实,这句话到什么时刻都是具有一定的借鉴意义。那我们开门见山,接下来放的三道题的解题思路就是靠的三大法宝的“变形”。
现在,看雪《安卓高级研修班(网课)》9月班开始招生啦!点击查看详情报名吧~
1
0x01 第一题:
统一“Frida和Objection”的战线
String str = MainActivity.this.username_et.getText().toString() + MainActivity.this.password_et.getText().toString();
function main(){
Java.perform(function() {
Java.use("com.kanxue.pediy1.VVVVV").VVVV.implementation = function(x,y){
var result = this.VVVV(x,y);
console.log("x,y,result:",x,y,result);
return result;
}
})
}
setImmediate(main)
./fri12820x64 -l 0.0.0.0:8888
objection -N -h 192.168.1.103 -p 8888 -g com.kanxue.pediy1 explore
android hooking watch class_method com.kanxue.pediy1.VVVVV.VVVV --dump-args --dump-backtrace --dump-return
android hooking watch class_method com.kanxue.pediy1.VVVVV.eeeee --dump-args --dump-backtrace --dump-return
function main(){
Java.perform(function() {
Java.openClassFile("/data/local/tmp/r0gson.dex").load();
const gson = Java.use("com.r0ysue.gson.Gson");
Java.use("com.kanxue.pediy1.VVVVV").eeeee.implementation = function(x){
var result = this.eeeee(x);
console.log("x,result:",x,gson.$new().toJson(result));
return result;
}
})
}
setImmediate(main)
String str = "6f452303f18605510aac694b0f5736beebf110bf";
byte[] byt = str.getBytes();
for (byte b : byt) {
System.out.println(b);
}
function firethehome(){
Java.perform(function(){
var VVVVV_Class = Java.use("com.kanxue.pediy1.VVVVV")
console.log("VVVVV_Class:", VVVVV_Class)
VVVVV_Class.eeeee.implementation=function(x){
var result = this.eeeee(x);
console.log("VVVVV.eeeee is hook! x ,result",x,JSON.stringify(result));
return result;
}
var ByteString = Java.use("com.android.okhttp.okio.ByteString");
console.log(ByteString);
var pSign = Java.use("java.lang.String").$new("6f452303f18605510aac694b0f5736beebf110bf").getBytes();
console.log( ByteString.of(pSign).hex());
// 爆破5位
for(var i = 9999;i<100000;i++){
console.log("i="+i);
var v = Java.use("java.lang.String").$new(String(i));
var vSign = VVVVV_Class.eeeee(v);
console.log("vSign:",ByteString.of(vSign).hex());
if(ByteString.of(vSign).hex() == ByteString.of(pSign).hex()){
console.log("i="+i);
break;
}
}
})
}
setImmediate(firethehome)
可以发现打印了两次,那么这就是flag。
function main(){
Java.perform(function() {
Java.openClassFile("/data/local/tmp/r0gson.dex").load();
const gson = Java.use("com.r0ysue.gson.Gson");
Java.use("com.kanxue.pediy1.VVVVV").eeeee.implementation = function(x){
var result = this.eeeee(x);
console.log("x,result:",x,gson.$new().toJson(result));
var v = result;
v = Java.array('byte',[54,102,52,53,50,51,48,51,102,49,56,54,48,53,53,49,48,97,97,99,54,57,52,98,48,102,53,55,51,54,98,101,101,98,102,49,49,48,98,102])
console.log(gson.$new().toJson(v));
return v;
}
})
}
setImmediate(main)
0x02 第二题:面对动态加载保护,
我们使用枚举ClassLoader来武装“Frida”斗争
str是username和password的字符串拼接,result是最后拿到flag的关键。
function main(){
Java.perform(function(){
Java.enumerateClassLoaders({
onMatch:function(loader){
try{
if(loader.findClass("com.kanxue.pediy1.VVVVV")){
console.log("success found com.kanxue.pediy1.VVVVV!",loader);
Java.classFactory.loader = loader;//替换ClassLoader为DexClassLoader
}
}catch(e){
console.log("found error!",e);
}
},onComplete(){console.log("enum completed!")}
})
Java.use("com.kanxue.pediy1.VVVVV").VVVV("12345");
});
}
function hookDex(){
Java.perform(function(){
Java.choose("com.kanxue.pediy1.MainActivity",{
onMatch:function(instance){
console.log("found instance:",instance);
console.log("invoke loadDexClass!",instance.loadDexClass());
},onComplete(){}
})
Java.choose("dalvik.system.DexClassLoader",{
onMatch:function(loader){
Java.classFactory.loader = loader;
console.log("the Loader:", Java.classFactory.loader)
},onComplete:function(){}
})
var VVVVV_Class = Java.use("com.kanxue.pediy1.VVVVV")
console.log("VVVVV_Class:", VVVVV_Class)
VVVVV_Class.eeeee.implementation=function(x){
var result = this.eeeee(x);
console.log("VVVVV.eeeee is hook!",result);
return result;
}
})
}
frida -U com.kanxue.pediy1 -l homework2.js
hookDex()
main()
function hookDex(){
Java.perform(function(){
Java.choose("com.kanxue.pediy1.MainActivity",{
onMatch:function(instance){
console.log("found instance:",instance);
console.log("invoke loadDexClass!",instance.loadDexClass());
},onComplete(){}
})
Java.choose("dalvik.system.DexClassLoader",{
onMatch:function(loader){
Java.classFactory.loader = loader;
console.log("the Loader:", Java.classFactory.loader)
},onComplete:function(){}
})
var VVVVV_Class = Java.use("com.kanxue.pediy1.VVVVV")
console.log("VVVVV_Class:", VVVVV_Class)
var ByteString = Java.use("com.android.okhttp.okio.ByteString");
console.log(ByteString);
var pSign = Java.use("java.lang.String").$new("7c133979c8fc45943815792c0288300687cf0a16").getBytes();
console.log( ByteString.of(pSign).hex());
for(var i = 9999;i<100000;i++){
console.log("i="+i);
var v = Java.use("java.lang.String").$new(String(i));
var vSign = VVVVV_Class.eeeee(v);
console.log("vSign:",ByteString.of(vSign).hex());
if(ByteString.of(vSign).hex() == ByteString.of(pSign).hex()){
console.log("i="+i);
break;
}
}
})
}
0x03 第三题:面对反Frida保护屡
试不爽的kill进程,采用Native Hook来强化建设我们的"Frida"
function hookstrcmp(){
Java.perform(function() {
console.log("I am a Hook function");
var strcmp = Module.findExportByName("libc.so","strcmp");//这里发现无论“libnative-lib.so”还是“libc.so”都是一样的地址
console.log("find strcmp:",strcmp);
Interceptor.attach(strcmp, {
onEnter: function (args) {
//hook住后打印strcmp的第一个参数和第二个参数的内容
if(ptr(args[1]).readCString().indexOf("REJECT")>=0){
console.log("[*] strcmp (" + ptr(args[0]).readCString() + "," + ptr(args[1]).readCString()+")");
this.isREJECT = true;
}
},onLeave:function(retval){
if(this.isREJECT){
console.log("the REJECT's result :",retval);
}
}
});
})
}
function hookstrcmp(){
Java.perform(function() {
console.log("I am a Hook function");
var strcmp = Module.findExportByName("libc.so","strcmp");//这里发现无论“libnative-lib.so”还是“libc.so”都是一样的地址
console.log("find strcmp:",strcmp);
Interceptor.attach(strcmp, {
onEnter: function (args) {
//hook住后打印strcmp的第一个参数和第二个参数的内容
if(ptr(args[1]).readCString().indexOf("REJECT")>=0){
console.log("[*] strcmp (" + ptr(args[0]).readCString() + "," + ptr(args[1]).readCString()+")");
this.isREJECT = true;
}
},onLeave:function(retval){
if(this.isREJECT){
retval.replace(0x1);
console.log("the REJECT's result :",retval);
}
}
});
})
}
function hookDex(){
Java.perform(function(){
Java.choose("com.kanxue.pediy1.MainActivity",{
onMatch:function(instance){
console.log("found instance:",instance);
console.log("invoke loadDexClass!",instance.loadDexClass());
},onComplete(){}
})
Java.choose("dalvik.system.DexClassLoader",{
onMatch:function(loader){
Java.classFactory.loader = loader;
console.log("the Loader:", Java.classFactory.loader)
},onComplete:function(){}
})
var VVVVV_Class = Java.use("com.kanxue.pediy1.VVVVV")
console.log("VVVVV_Class:", VVVVV_Class)
var ByteString = Java.use("com.android.okhttp.okio.ByteString");
console.log(ByteString);
var pSign = Java.use("java.lang.String").$new("971b82e071392d8293e57b39fc5056c731517d4e").getBytes();
console.log( ByteString.of(pSign).hex());
//爆破
for(var i = 9999;i<100000;i++){
console.log("i="+i);
var v = Java.use("java.lang.String").$new(String(i));
var vSign = VVVVV_Class.eeeee(v);
console.log("vSign:",ByteString.of(vSign).hex());
if(ByteString.of(vSign).hex() == ByteString.of(pSign).hex()){
console.log("i="+i);
break;
}
}
})
}
function hookstrcmp(){
Java.perform(function() {
console.log("I am a Hook function");
var strcmp = Module.findExportByName("libc.so","strcmp");//这里发现无论“libnative-lib.so”还是“libc.so”都是一样的地址
console.log("find strcmp:",strcmp);
//Hook strcmp
Interceptor.attach(strcmp, {
onEnter: function (args) {
//hook住后打印strcmp的第一个参数和第二个参数的内容
if(ptr(args[1]).readCString().indexOf("REJECT")>=0){
console.log("[*] strcmp (" + ptr(args[0]).readCString() + "," + ptr(args[1]).readCString()+")");
this.isREJECT = true;
}
},onLeave:function(retval){
if(this.isREJECT){
retval.replace(0x1);
console.log("the REJECT's result :",retval);
}
}
});
})
}
setImmediate(hookstrcmp);
1
0x04 结语
看雪ID:一颗金柚子
https://bbs.pediy.com/user-879358.htm
*本文由看雪论坛 一颗金柚子 原创,转载请注明来自看雪社区。
推荐文章++++
好书推荐